package cn.pconline.autoclub.service;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.gelivable.dao.GeliDao;
import org.gelivable.dao.GeliOrm;
import org.gelivable.dao.Mid;
import org.gelivable.dao.SqlBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;

import cn.pconline.autoclub.entity.Subject;
import cn.pconline.autoclub.entity.UserSubject;
import cn.pconline.autoclub.util.Pager;

public class UserSubjectService {

    @Autowired
    private GeliOrm geliOrm;
    @Autowired
    private GeliDao geliDao;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private PagerService pagerService;
    private static final Logger log = LoggerFactory.getLogger(UserSubjectService.class);
    
	/**
	 * 创建用户话题
	 * @param subject  话题
	 * @param isTop	 是否置顶
	 */
	public void createUserSubject(Subject subject ,long dynaInfoId, int isTop){
		UserSubject userSubject = new UserSubject();
		userSubject.setUserId(subject.getCreateBy());
		userSubject.setSubjectId(subject.getSubjectId());
		userSubject.setIsTop( isTop );
		userSubject.setStatus(subject.getStatus());
		userSubject.setDynaInfoId(dynaInfoId);
		userSubject.setCreateAt( userSubject.getCreateAt());
		geliDao.create( userSubject );
	}
	
	/**
	 * 根据id查找用户话题
	 * @param createBy
	 * @param subjectId
	 * @param dynaInfoId
	 * @return
	 */
	public UserSubject findUserSubjectById(long createBy,long subjectId,long dynaInfoId){
		try {
	        return geliDao.find(UserSubject.class, createBy, new Mid(createBy,subjectId,dynaInfoId));
        }
        catch( EmptyResultDataAccessException e ) {
        	log.warn("cant't find UserSubject which userId:{} subjectId:{},dynaInfoId:{}",createBy,subjectId,dynaInfoId);
	        return null;
        }
	}
	
	/**
	 * 逻辑删除用户话题
	 * @param createBy
	 * @param subjectId
	 * @param dynaInfoId
	 * @return
	 */
	public long deleteUserSubject(long createBy,long subjectId,long dynaInfoId){
		try {
	        UserSubject userSubject=geliDao.find(UserSubject.class, createBy, new Mid(createBy,subjectId,dynaInfoId));
	        if(userSubject==null) return 0;
	        userSubject.setStatus(UserSubject.STATUS_DELETE);
	        return geliDao.update( userSubject, "status");
        }
        catch( EmptyResultDataAccessException e ) {
        	log.warn("cant't find UserSubject which userId:{} subjectId:{},dynaInfoId:{}",createBy,subjectId,dynaInfoId);
        }
        return 0;
	}
	
	/**
	 * 更新置顶字段
	 * @param createBy
	 * @param subjectId
	 * @param dynaInfoId
	 * @param isTop
	 * @return
	 */
	public int updateTop(long createBy,long subjectId,long dynaInfoId,int isTop){
		try {
			UserSubject userSubject=geliDao.find(UserSubject.class, createBy, new Mid(createBy,subjectId,dynaInfoId));
			if(userSubject==null) return 0;
			userSubject.setIsTop( isTop );
			return geliDao.update( userSubject, "is_top" );
        }
        catch( EmptyResultDataAccessException e ) {
        	log.warn("cant't find UserSubject which userId:{} subjectId:{},dynaInfoId:{}",createBy,subjectId,dynaInfoId);
        }
        return 0;
	}
    
    /**
     * 根据用户id列举所以用户参与过的话题
     * @param userId
     * @return
     */
    public List<Subject> listSubjectByUser(long userId){
    	SqlBuilder sql = new SqlBuilder();
    	sql.appendSql("select subject_id from ").appendSql(geliOrm.getTableName(UserSubject.class, userId ))
			.appendSql(" where status = ").appendValue(Subject.STATUS_NORMAL);
    	List<Long> idList =jdbcTemplate.query(sql.getSql(), sql.getValues(), new ResultSetExtractor<List<Long>>(){
    		
			@Override
            public List<Long> extractData( ResultSet rs ) throws SQLException, DataAccessException {
				List<Long> list = new ArrayList<Long>();
	            while (rs.next()) {
                    long subjectId = rs.getLong("subject_id");
                    list.add( subjectId);
                }
	            return list;
            }
    		
    	});
    	try {
	        List<Subject> list = geliDao.list( Subject.class, idList.toArray() );
	        return list;
        }
        catch( EmptyResultDataAccessException e ) {
        	log.warn("The userId {} can't find all subject which subjectIds in {}", userId,idList.toString());
	        return null;
        }
    	
    }  
    
    /**
     * 根据用户id列举所属用户参与过的话题以阅读数倒序
     * @param userId
     * @return
     */
    public List<Subject> listSubjectByUserIdByHot(long userId){
    	List<Long> idList = getSubjectIdByUserId(userId);
    	if(idList == null || idList.size() == 0){
    		return null;
    	}
    	try {
    		SqlBuilder sql = new SqlBuilder();
    		sql.appendSql(" select subject_id from ").appendSql(geliOrm.getTableName(Subject.class))
    		    .appendSql(" where status = ").appendValue(Subject.STATUS_NORMAL)
    		    .appendSql(" and subject_id in ").appendValues(idList.toArray())
    		    .appendSql(" order by pv_count desc,create_at desc ");
	        List<Subject> list = geliDao.list( Subject.class, sql.getSql(), sql.getValues());
	        return list;
        }
        catch( EmptyResultDataAccessException e ) {
        	log.warn("The userId {} can't find all subject which subjectIds in {}", userId,idList.toString());
        	return Collections.emptyList();
        }
    	
    } 
    
    public Pager<Subject> pageByUserIdByHot(long userId,int pageNo,int pageSize){
    	List<Long> idList = getSubjectIdByUserId(userId);
    	if(idList == null || idList.size() == 0){
    		return null;
    	}
		SqlBuilder sql = new SqlBuilder();
		sql.appendSql(" select subject_id from ").appendSql(geliOrm.getTableName(Subject.class))
		    .appendSql(" where status = ").appendValue(Subject.STATUS_NORMAL)
		    .appendSql(" and subject_id in ").appendValues(idList.toArray())
		    .appendSql(" order by pv_count desc,create_at desc ");
		Pager<Subject> pager =pagerService.pager( Subject.class, sql, pageNo, pageSize );
		return pager;
    }
      
    private List<Long> getSubjectIdByUserId(long userId){
    	SqlBuilder sql = new SqlBuilder();
    	sql.appendSql("select subject_id from ").appendSql(geliOrm.getTableName(UserSubject.class, userId))
			.appendSql(" where status = ").appendValue(Subject.STATUS_NORMAL)
    	    .appendSql(" and user_id = ").appendValue(userId);
    	List<Long> idList =jdbcTemplate.query(sql.getSql(), sql.getValues(), new ResultSetExtractor<List<Long>>(){
			@Override
            public List<Long> extractData( ResultSet rs ) throws SQLException, DataAccessException {
				List<Long> list = new ArrayList<Long>(rs.getRow());
	            while (rs.next()) {
                    long subjectId = rs.getLong("subject_id");
                    if(!list.contains( subjectId )){
                    	list.add( subjectId);
                    }
                }
	            return list;
            }
    		
    	});
    	return idList;
    }
}
